﻿using System.Runtime.InteropServices;

namespace Ex03.GarageManagementSystem.ConsoleUI
{
    /// <summary>
    /// This class deals with the console clear screen.
    /// The code was based on code taken from <see cref="http://forums.asp.net/t/572517.aspx/1"/>
    /// </summary>
    public class ScreenCleaner
    {		
        private const int k_STD_OUTPUT_HANDLE  = -11;
        private const byte k_EMPTY = 32;

        [StructLayout(LayoutKind.Sequential)]
        private struct COORD
        {
            public short m_X;
            public short m_Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct SMALL_RECT
        {
            public short m_Left;
            public short m_Top;
            public short m_Right;
            public short m_Bottom;
        }
		
        [StructLayout(LayoutKind.Sequential)]
        private struct	CONSOLE_SCREEN_BUFFER_INFO
        {
            public COORD m_DwSize;
            public COORD m_DwCursorPosition;
            public int m_WAttributes;
            public SMALL_RECT m_SrWindow;
            public COORD m_DwMaximumWindowSize;
        }

        [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int GetStdHandle(int nStdHandle);

        [DllImport("kernel32.dll", EntryPoint = "FillConsoleOutputCharacter", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int FillConsoleOutputCharacter(int hConsoleOutput, byte cCharacter, int nLength, COORD dwWriteCoord, ref int lpNumberOfCharsWritten);

        [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int GetConsoleScreenBufferInfo(int hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

        [DllImport("kernel32.dll", EntryPoint = "SetConsoleCursorPosition", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int SetConsoleCursorPosition(int hConsoleOutput, COORD dwCursorPosition);

        private int hConsoleHandle;

        public ScreenCleaner()
        {
            hConsoleHandle = GetStdHandle(k_STD_OUTPUT_HANDLE);
        }

        public void Clear()
        {
            int hWrittenChars = 0;
            CONSOLE_SCREEN_BUFFER_INFO strConsoleInfo = new CONSOLE_SCREEN_BUFFER_INFO();			
            COORD Home;		
            Home.m_X = Home.m_Y = 0;
            GetConsoleScreenBufferInfo(hConsoleHandle, ref strConsoleInfo);
            FillConsoleOutputCharacter(hConsoleHandle, k_EMPTY, strConsoleInfo.m_DwSize.m_X * strConsoleInfo.m_DwSize.m_Y, Home, ref hWrittenChars);
            SetConsoleCursorPosition(hConsoleHandle, Home);
        }
    }
}
